home *** CD-ROM | disk | FTP | other *** search
- Newsgroups: comp.lang.c
- Path: lyra.csx.cam.ac.uk!warwick!bsmail!talisker!nathan
- From: nathan@pact.srf.ac.uk (Nathan Sidwell)
- Subject: Re: division problem
- Message-ID: <DM1KMy.G3p@uns.bris.ac.uk>
- Sender: usenet@uns.bris.ac.uk (Usenet news owner)
- Nntp-Posting-Host: talisker.pact.srf.ac.uk
- Organization: Inmos
- X-Newsreader: TIN [version 1.2 PL2]
- References: <31097D77.11AA@rain.org> <26JAN199622082450@erich.triumf.ca> <4eh246$u6h@airdmhor.gen.nz> <4ej4ha$66@fountain.mindlink.net> <DLzvGG.2rn@uns.bris.ac.uk> <Pine.SOL.3.90.960130150923.21923F-100000@flute>
- Date: Wed, 31 Jan 1996 10:47:22 GMT
-
- Darrell Grainger (a378grai@cdf.toronto.edu) wrote:
- : On Tue, 30 Jan 1996, Nathan Sidwell (me) wrote:
-
- : > Still no need to use floating point,
- : > celcius = ((fahrenheit - 32) * 5 + 4) / 9
-
- : This ALMOST does the trick but 4/9 = 0.44444444... and 5/9 = 0.555555....
- : What you really want to do to eliminate the rounding errors is add 0.5 to
- : the number, e.g. 1.49999... + 0.5 = 1.9999... and (int)1.9999... = 1. So
- : 1.49999... rounds down to 1. Then 1.5 + 0.5 = 2.0 and (int)2.0 = 2. So
- : 1.5 rounds up to 2. This is what most people consider correct rounding.
- Integers and floating point numbers are not real numbers. This effects
- what 'correct' rounding is.
-
- In this case the middle values are 4/9 and 5/9. We don't need to consider
- the case 4.5/9, which is what you're trying to do.
-
- : In your 'trick' you would have 1.5 + 0.4444... = 1.9444... and
- : (int)1.9444... = 1. This means that 1.5 rounds down to 1. This is not
- As I've just said, this case NEVER HAPPENS.
-
- : proper. It is close but not proper. Alternatively, adding 5/9th would round
- : up certain numbers it should not.
- adding 5/9 would round up the 4/9, which is wrong.
-
- You are correct in pointing out that 4 ALMOST does the trick, but incorrect
- in your analysis.
-
- Adding 4 will give the correct rounding for values >= 0 or if division
- truncates to most neg int.
- Adding 5 will give incorrect rounding, whatever the domain of the dividend.
- Subtracting 4 gives correct rounding for values < 0 if division rounds
- towards zero.
-
- What adding 4 is doing is moving the desired dividend values into the next
- integral multiple of 9. In this case the possible remainders are integers
- in the range [0,9)% (assuming +ve dividend or division rounding to most neg).
- We want remainders [0,5) to round down and [5,9) to round up.
- Adding 4 will move the these two ranges to [4,9) and [9,13), which
- indeed have the desired rounding behaviour.
-
- For -ve dividend and division rounding to zero, the remainders are in the
- range (-9,0]. (-9,-5] wants to round down and (-5,0] round up. So we need to
- subtract 4, to move to the ranges (-13,-9] and (-9,-4].
-
- For systems where division rounds towards zero, the expression should be
-
- celcius = ((fahrenheit - 32) * 5 + (fahrenheit < 32 ? -4 : 4)) / 9
-
- Depending on the target architecture and the strength of the compiler,
- the conditional expression could be evaluated with bit masking operations.
-
- nathan
-
- % for those unfamiliar, the notation [x,y) indicates the interval
- of values from x (inclusive) up to, but not including, y.
- --
- Nathan Sidwell Holder of the Xmris home page
- Chameleon Architecture Group at SGS-Thomson, formerly Inmos
- http://www.pact.srf.ac.uk/~nathan/ Tel 0117 9707182
- nathan@inmos.co.uk or nathan@bristol.st.com or nathan@pact.srf.ac.uk
-